#include "aceMesh_performance.h"
#include <iostream>
#include <cassert>
#include <sys/stat.h> 

#include "papi.h"

namespace AceMesh_runtime {

thread_ctl aceMesh_performance::my_output("aceMesh_performance/aceMesh_performance_");


#define PAPI_FORCE PAPI_L3_TCM
//#define PAPI_FORCE PAPI_TLB_DM

void aceMesh_performance::init()
{
    if (PAPI_library_init(PAPI_VER_CURRENT) !=
        PAPI_VER_CURRENT)
        exit(1);
    int status =  mkdir("aceMesh_performance", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    //std::cout << "status: " << status <<std::endl;
    //TODO
}

void aceMesh_performance::uninit()
{
    /* Shutdown PAPI */
    PAPI_shutdown();
}

aceMesh_performance::aceMesh_performance(): 
    event_set(PAPI_NULL)
{
}


aceMesh_performance::~aceMesh_performance()
{
    /* Clean up EventSet */
    if (PAPI_cleanup_eventset(event_set) != PAPI_OK)   
        exit(-1);
    /* Destroy the EventSet */
    if (PAPI_destroy_eventset(&event_set) != PAPI_OK)  
        exit(-1);

}



void aceMesh_performance::thread_init()
{
    if (PAPI_thread_init(pthread_self) != PAPI_OK)
        exit(1);

    int retval = PAPI_create_eventset (&event_set);
    assert(retval==PAPI_OK);
    retval = PAPI_add_event(event_set, PAPI_FORCE);
    //retval = PAPI_add_event(event_set, PAPI_L3_TCM);
    assert(retval==PAPI_OK);
}

void aceMesh_performance::record_start()
{
    //my_output.print("L3 cache miss : ");
    //long long thold = 1<<31ll;

    //retval = PAPI_overflow(event_set, PAPI_L3_TCM, 
    //    thold, 0, handler);
    //
    int retval = PAPI_start (event_set);
    assert(retval==PAPI_OK);
    PAPI_read(event_set, values1);
    assert(retval==PAPI_OK);
}
void aceMesh_performance::record_end()
{
    int retval = PAPI_stop (event_set,values2);
    assert(retval==PAPI_OK);

    //std::cout << "L3 cache miss : " << 
    //    values2[0] - values1[0] << std::endl; 
    //std::cout << "1" << std::endl;
    //std::cout << pthread_self() << std::endl;
    my_output.print("PAPI FORCE : ");
    my_output.print_long_long(values2[0] - values1[0]);
}
}
